package com.pureut.system.service.impl;

import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.StringUtils;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.system.api.OrderFeignService;
import com.pureut.system.api.domain.CustomerManagement;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.domain.MaterialCoding;
import com.pureut.system.domain.MaterialFinished;
import com.pureut.system.domain.SysTheAlarm;
import com.pureut.system.domain.dto.MaterialFinishedDto;
import com.pureut.system.domain.dto.MaterialMqDto;
import com.pureut.system.domain.dto.ProjectRecursionDto;
import com.pureut.system.domain.vo.MaterialAlarmVo;
import com.pureut.system.domain.vo.MaterialFinishedVo;
import com.pureut.system.export.MaterialFinishedExport;
import com.pureut.system.mapper.MaterialBomHalfMapper;
import com.pureut.system.mapper.MaterialCodingMapper;
import com.pureut.system.mapper.MaterialFinishedMapper;
import com.pureut.system.mapper.SysTheAlarmMapper;
import com.pureut.system.service.IMaterialFinishedService;
import com.pureut.system.util.MaterialMqUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 成品信息实现类
 * @Param
 * @Date 22-11-28
 * @Author hl
 **/
@Service
public class MaterialFinishedServiceImpl implements IMaterialFinishedService {

    @Resource
    private MaterialFinishedMapper materialFinishedMapper;

    @Resource
    private SysTheAlarmMapper sysTheAlarmMapper;

    @Resource
    private MaterialAwmateriaServiceImpl materialAwmateriaServiceImpl;

    @Resource
    private MaterialCodingMapper materialCodingMapper;

    @Resource
    private SysMidSplitServiceImpl sysMidSplitServiceImpl;

    @Resource
    private OrderFeignService orderFeignService;

    //BomMapper
    @Resource
    private MaterialBomHalfMapper materialBomHalfMapper;

    /**
     * 新增成品信息
     *
     * @param materialFinished 成品信息
     * @return 成品集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertFinished(MaterialFinished materialFinished) throws Exception {
        materialFinished.setDeptId(SecurityUtils.getDeptId());
        materialFinished.setMaterialCode(sysMidSplitServiceImpl.splitStr(materialCodingMapper.selectCodingTypeThe(materialFinished.getMaterialType())));
        materialFinished.setCreateBy(SecurityUtils.getUsername());
        int ins = materialFinishedMapper.insertFinished(materialFinished);
        if (ins > 0) {

            if (materialFinished.getAlarmCode()!=null) {

                List<SysTheAlarm> list = materialAwmateriaServiceImpl.alarmConfiguration(materialFinished.getAlarmCode());
                long op = materialFinished.getMaterialId();
                String materialCode = materialFinished.getMaterialCode();
                for (SysTheAlarm sysTheAlarm :
                        list) {

                    String roles = "";
                    for (int i = 0; i < sysTheAlarm.getRoleIds().size(); i++) {

                        roles = roles + sysTheAlarm.getRoleIds().get(i);
                        if (sysTheAlarm.getRoleIds().size()-1!=i){
                            roles = roles + ",";
                        }

                    }

                    sysTheAlarm.setAlarmRoleId(roles);

                    sysTheAlarm.setAlarmAssociatedId(op);
                    sysTheAlarm.setAlarmOfMaterial(4);
                    sysTheAlarm.setAlarmMaterialCode(materialCode);
                }

                if (list.size()!=0) {
                    ins = sysTheAlarmMapper.insertSysTheAlarm(list);
                }
            }
            if (ins == 0) {
                throw new SQLException("抛出异常");
            }
            MaterialMqDto mq = new MaterialMqDto();
            mq.setMaterialGheavy(materialFinished.getMaterialGheavy());
            mq.setMaterialCode(materialFinished.getMaterialCode());
            mq.setMaterialName(materialFinished.getMaterialName());
            mq.setMaterialSpec(materialFinished.getMaterialSpec());
            mq.setMaterialCategory(4);
            mq.setMaterialType(materialFinished.getMaterialType());
            mq.setMaterialRatio(materialFinished.getMaterialRatio());
            mq.setMaterialNet(materialFinished.getMaterialNet());
            mq.setMaterialNetType(materialFinished.getMaterialNetType());
            mq.setMaterialInspection(materialFinished.getMaterialInspection());
            mq.setMaterialUnit(String.valueOf(materialFinished.getMaterialUnit()));
            mq.setMaterialHair(materialFinished.getMaterialHair());
            mq.setMaterialClosed(materialFinished.getMaterialClosed());
            mq.setMaterialReminder(materialFinished.getMaterialReminder());//复检提醒
            mq.setMaterialQuality(materialFinished.getMaterialQuality());//保质期
            mq.setMaterialOverdue(materialFinished.getMaterialOverdue());//过期提醒
            mq.setMaterialMinSecurity(materialFinished.getMaterialMinSecurity());//最小安全库存

            MaterialMqUtil.materialMqSend(mq);
        }
        return ins;
    }

    /**
     * 删除成品信息
     *
     * @param materialId 成品id
     * @return 成品集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteFinishedById(String materialId) throws Exception {
        String[] materialIdS = materialId.split(",");
        //同步删除成品信息
        MaterialMqDto mq = new MaterialMqDto();
        List<String> materialIdList = Arrays.asList(materialId.split(","));
        String finishedStr = materialFinishedMapper.getFinishedById(materialIdList);
        mq.setMaterialCode(finishedStr);
        //删除标识
        mq.setMark(3);
        MaterialMqUtil.materialMqSendDelete(mq);

        int is = materialFinishedMapper.deleteFinishedById(materialIdS);
        if (is > 0) {
            sysTheAlarmMapper.deleteSysTheAlarmById(materialIdS);
            if (is == 0) {
                throw new SQLException("抛出异常");
            }
        }
        return is;
    }

    /**
     * 查询成品信息
     *
     * @param materialFinished 成品信息
     * @return 原料集合
     */
    @Override
    @DataScope(deptAlias = "t1")
    public List<MaterialFinishedDto> selectFinishedList(MaterialFinishedVo materialFinished) {
        List<SysDictData> netArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> netMap = netArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<SysDictData> netArray2 = DictUtils.getDictCache("sys_of_type");
        Map<String, String> netMap2 = netArray2.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<SysDictData> netArray3 = DictUtils.getDictCache("sys_type_net");
        Map<String, String> netMap3 = netArray3.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<MaterialFinishedDto> list = materialFinishedMapper.selectFinishedList(materialFinished);
        for (MaterialFinishedDto dto :
                list) {
            dto.setMaterialUnitDict(netMap.get(String.valueOf(dto.getMaterialUnit())));
            dto.setMaterialNetDict(netMap2.get(String.valueOf(dto.getMaterialNet())));
            dto.setMaterialNetTypeDict(netMap3.get(String.valueOf(dto.getMaterialNetType())));
            dto.setBomType("4");
            dto.setBomTypeDict("成品");
        }
        return list;
    }

    /**
     * 查询单个成品信息
     *
     * @param materialId 成品信息ID
     * @return 成品信息集合
     */
    @Override
    public MaterialFinishedDto selectFinishedById(long materialId) {
        MaterialFinishedVo materialFinished = new MaterialFinishedVo();
        materialFinished.setMaterialId(materialId);
        List<MaterialFinishedDto> list = materialFinishedMapper.selectFinishedList(materialFinished);
        MaterialFinishedDto materialFinishedDto = new MaterialFinishedDto();
        materialFinishedDto = list.get(0);
        int alarmOfMaterial = 4;
        List<SysTheAlarm> theList = sysTheAlarmMapper.selectSysTheAlarmList(materialId, alarmOfMaterial);
        MaterialAlarmVo materialAlarmVo = materialAwmateriaServiceImpl.alarmConfigtType(theList);
        materialFinishedDto.setAlarmCode(materialAlarmVo);
        //铺网类型
        List<SysDictData> dictList = DictUtils.getDictCache("sys_of_type");
        //网型
        List<SysDictData> dictList2 = DictUtils.getDictCache("sys_type_net");
        //单位
        List<SysDictData> dictList3 = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> actualMap = dictList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        Map<String, String> actualMap2 = dictList2.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        Map<String, String> actualMap3 = dictList3.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        materialFinishedDto.setMaterialNetDict(actualMap2.get(materialFinishedDto.getMaterialNet()));
        materialFinishedDto.setMaterialNetTypeDict(actualMap.get(materialFinishedDto.getMaterialNetType()));
        materialFinishedDto.setMaterialUnitDict(actualMap3.get(materialFinishedDto.getMaterialUnit()));
        return materialFinishedDto;
    }

    /**
     * 修改成品信息
     *
     * @param
     * @return 成品信息集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMaterialFinishedEdit(MaterialFinished materialFinished) throws Exception {
        int ors = materialFinishedMapper.updateMaterialFinishedEdit(materialFinished);
        if (ors > 0) {
            long materialId = materialFinished.getMaterialId();
            sysTheAlarmMapper.deleteSysTheAlarmOnById(materialId);
            if (ors > 0) {
                long sy = materialFinished.getMaterialId();
                String materialCode = materialFinished.getMaterialCode();
                List<SysTheAlarm> list = materialAwmateriaServiceImpl.alarmConfiguration(materialFinished.getAlarmCode());
                for (SysTheAlarm sysTheAlarm :
                        list) {

                    String roles = "";
                    for (int i = 0; i < sysTheAlarm.getRoleIds().size(); i++) {

                        roles = roles + sysTheAlarm.getRoleIds().get(i);
                        if (sysTheAlarm.getRoleIds().size()-1!=i){
                            roles = roles + ",";
                        }

                    }

                    sysTheAlarm.setAlarmRoleId(roles);

                    sysTheAlarm.setAlarmAssociatedId(sy);
                    sysTheAlarm.setAlarmOfMaterial(4);
                    sysTheAlarm.setAlarmMaterialCode(materialCode);
                }

                if (list.size()!=0) {
                    ors = sysTheAlarmMapper.insertSysTheAlarm(list);
                }
                if (ors == 0) {
                    throw new SQLException("抛出异常");
                }
            } else {
                throw new SQLException("抛出异常");
            }
        }
        MaterialMqDto mq = new MaterialMqDto();
        mq.setMaterialCode(materialFinished.getMaterialCode());
        mq.setMaterialName(materialFinished.getMaterialName());
        mq.setMaterialSpec(materialFinished.getMaterialSpec());
        mq.setMaterialCategory(4);
        mq.setMaterialType(materialFinished.getMaterialType());
        mq.setMaterialRatio(materialFinished.getMaterialRatio());
        mq.setMaterialGheavy(materialFinished.getMaterialGheavy());
        mq.setMaterialNet(materialFinished.getMaterialNet());
        mq.setMaterialNetType(materialFinished.getMaterialNetType());
        mq.setMaterialUnit(String.valueOf(materialFinished.getMaterialUnit()));
        mq.setMaterialHair(materialFinished.getMaterialHair());
        mq.setMaterialClosed(materialFinished.getMaterialClosed());
        mq.setMaterialReminder(materialFinished.getMaterialReminder());//复检提醒
        mq.setMaterialQuality(materialFinished.getMaterialQuality());//保质期
        mq.setMaterialOverdue(materialFinished.getMaterialOverdue());//过期提醒
        mq.setMaterialMinSecurity(materialFinished.getMaterialMinSecurity());//最小安全库存
        MaterialMqUtil.materialMqSend(mq);

        materialBomHalfMapper.updateBomInfo(materialFinished.getMaterialName(),materialFinished.getMaterialCode());
        materialBomHalfMapper.updateBomDetail(materialFinished.getMaterialName(),materialFinished.getMaterialCode());
        return ors;
    }

    /**
     * 冻结/解冻成品信息
     *
     * @param
     * @return 成品信息集合
     */
    @Override
    public int updateFinishedEditFreeze(MaterialFinished materialFinished) {
        return materialFinishedMapper.updateFinishedEditFreeze(materialFinished);
    }

    /**
     * 树结构展示
     *
     * @param
     * @return 成品信息集合
     */
    @Override
    public List<ProjectRecursionDto> selectChildrenFinishedThe() {
        return MaterialAwmateriaServiceImpl.buildMenuTree(materialFinishedMapper.selectChildrenFinishedThe());
    }

    /**
     * 根据物料编码查询详情（成品信息）
     *
     * @param materialCode
     * @return
     */
    @Override
    public MaterialFinished selectMaterialFinishedMaterialCode(String materialCode) {
        return materialFinishedMapper.selectMaterialFinishedMaterialCode(materialCode);
    }

    /**
     * 成品信息导入
     * @param coCustomer
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importMouldData(List<MaterialFinishedExport> coCustomer) {
        if (StringUtils.isNull(coCustomer) || coCustomer.size() == 0) {
            throw new GlobalException("导入成品信息不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        //原料单位
        List<SysDictData> levelArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //网型
        List<SysDictData> netArray = DictUtils.getDictCache("sys_of_type");
        Map<String, String> netMap = netArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //铺网类型
        List<SysDictData> netTypeArray = DictUtils.getDictCache("sys_type_net");
        Map<String, String> netTypeMap = netTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (MaterialFinishedExport mouldModelExport : coCustomer) {
            MaterialFinished materialFinished = new MaterialFinished();
            try {
                if (mouldModelExport.getMaterialName() == null || mouldModelExport.getMaterialType() == null || mouldModelExport.getMaterialGheavy() == null || mouldModelExport.getMaterialNet() == null || mouldModelExport.getMaterialNetType() == null || mouldModelExport.getMaterialCustomer() == null ||mouldModelExport.getMaterialUnit() ==null ) {
                    throw new GlobalException("存在必填字段为空,请核实");
                }

                materialFinished.setMaterialName(mouldModelExport.getMaterialName());

                //通过原料类别名称查出原料类别id
                MaterialCoding materialCoding = materialCodingMapper.getMaterilTypeId(mouldModelExport.getMaterialType());

                if (materialCoding==null){
                    throw new GlobalException("不存在该成品类别导入失败");
                }
                materialFinished.setMaterialSpec(mouldModelExport.getMaterialSpec());
                materialFinished.setMaterialType((int) materialCoding.getCodingId());

                materialFinished.setMaterialGheavy(Double.parseDouble(mouldModelExport.getMaterialGheavy()));//克重

                if (mouldModelExport.getMaterialQuality()!=null) {
                    materialFinished.setMaterialQuality(Integer.parseInt(mouldModelExport.getMaterialQuality()));
                }
                if (mouldModelExport.getMaterialOverdue()!=null){
                    materialFinished.setMaterialOverdue(Integer.parseInt(mouldModelExport.getMaterialOverdue()));
                }
                if (mouldModelExport.getMaterialInspection()!=null){
                    materialFinished.setMaterialInspection(Integer.parseInt(mouldModelExport.getMaterialInspection()));
                }
                if (mouldModelExport.getMaterialReminder()!=null){
                    materialFinished.setMaterialReminder(Integer.parseInt(mouldModelExport.getMaterialReminder()));
                }
                if (mouldModelExport.getMaterialMinSecurity()!=null){
                    materialFinished.setMaterialMinSecurity(Integer.parseInt(mouldModelExport.getMaterialMinSecurity()));
                }

                //原料单位
                for (Map.Entry<String, String> entry : levelMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getMaterialUnit())) {
                        materialFinished.setMaterialUnit(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }

                //网型
                for (Map.Entry<String, String> entry : netMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getMaterialNet())) {
                        materialFinished.setMaterialNet(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }

                //铺网类型
                for (Map.Entry<String, String> entry : netTypeMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getMaterialNetType())) {
                        materialFinished.setMaterialNetType(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }

                //通过客户名称查出客户id
                String customerName = mouldModelExport.getMaterialCustomer();
                CustomerManagement customerManagement = orderFeignService.getCustomerId(customerName);
                if (customerManagement==null){
                    throw new GlobalException("不存在该客户");
                }
                materialFinished.setMaterialCustomerId(customerManagement.getId());

                //超收标志
                if ("开".equals(mouldModelExport.getMaterialClosed())){
                    materialFinished.setMaterialClosed(1);
                }else{
                    materialFinished.setMaterialClosed(2);
                }
                if ("开".equals(mouldModelExport.getMaterialHair())){
                    materialFinished.setMaterialHair(1);
                }else{
                    materialFinished.setMaterialHair(2);
                }

                //超发标志

                int i = insertFinished(materialFinished);
                    if (i==0){
                     throw new GlobalException("导入失败");
                    }

                successNum++;
                successMsg.append(successNum).append("、成品信息 ").append(mouldModelExport.getMaterialName()).append(" 导入成功");

            } catch (Exception e) {
                failureNum++;
                String msg = failureNum + "、成品名称 " + mouldModelExport.getMaterialName() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new GlobalException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }

        return successMsg.toString();
    }

    /**
     *  根据物料编码查询详情(委外订单明细列表fegin调用)
     */
    @Override
    public MaterialFinishedDto getFinishViewByMaterialCode(String materialCode) {
        return materialFinishedMapper.getFinishViewByMaterialCode(materialCode);
    }

}
